In [2]:
import numpy as np
import matplotlib.pyplot as plt
In [313]:
X = np.array([[1,1],[2,2], [1,6], [1,2], [1,4], [3, 2]])
y = np.array([0, 0, 1, 0, 1, 1])
_ = plt.scatter(X[:,0], X[:,1], c = y)
In [20]:
X_p = np.append(np.ones((X.shape[0], 1)), X, axis=1)
In [21]:
np.ones((X.shape[0] + 1, 1))
Out[21]:
array([[1.],
       [1.],
       [1.]])
In [19]:
X_p
Out[19]:
array([[1., 1., 1.],
       [2., 2., 1.]])
In [30]:
np.random.rand(1,3)
Out[30]:
array([[0.09348572, 0.99508685, 0.31798598]])
In [138]:
def draw_contour(clf, X):
    x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
    y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1

    plot_step = 100
    
    xx, yy = np.meshgrid(np.linspace(x_min, x_max, plot_step),
    np.linspace(y_min, y_max, plot_step))
    
    Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])
    
    Z = Z.reshape(xx.shape)
    cs = plt.contourf(xx, yy, Z, cmap=plt.cm.RdYlBu, alpha=0.3)
In [311]:
class Perceptron:
    def __init__(self, X, alpha=0.1, max_epochs=500):
        self._X = np.append(np.ones((X.shape[0], 1)), X, axis=1)
        self._alpha = alpha
        self._max_epochs = max_epochs
        
        self._W = np.random.rand(1, self._X.shape[1])
        
    def sigmoid(self, x):
        return 1 / (1 + np.exp(-x))
        
    def train(self, Y):
        for k in range(self._max_epochs):
            if k % 5 == 0:
                draw_contour(self, X)
                _ = plt.scatter(X[:,0], X[:,1], c=Y)
                plt.show()

            for i in range(self._X.shape[0]):
                x = self._X[i]
                y = Y[i]
                
                x_t = np.array([x]).T

                H = (self._W).dot(x_t)
                A = self.sigmoid(H)

                dEdA = A - y
                dAdH = A * (1 - A)
                dHdw = x

                D = dEdA * dAdH * dHdw
                self._W -= self._alpha * D
                
    def predict(self, X):
        X_extended = np.append(np.ones((X.shape[0], 1)), X, axis=1)
        return np.array([int(y > 0.5) for y in self.sigmoid(self._W.dot(X_extended.T).ravel())])
In [314]:
perceptron = Perceptron(X)
perceptron.train(y)
In [315]:
perceptron.predict(X)
Out[315]:
array([0, 0, 1, 0, 1, 1])
In [296]:
draw_contour(perceptron, X)
_ = plt.scatter(X[:,0], X[:,1], c=y)